package com.qf.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.qf.client.OrdersClient;
import com.qf.pojo.resp.BaseResp;
import com.qf.pojo.vo.Orders;
import com.qf.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@Service
public class PayServiceImpl implements PayService {

    @Value("${alipay.appid}")
    private String APP_ID;

    @Value("${alipay.app_private_key}")
    private String APP_PRIVATE_KEY;

    @Value("${alipay.alipay_public_key}")
    private String ALIPAY_PUBLIC_KEY;

    @Value("${alipay.url}")
    private String url;

    @Autowired
    OrdersClient ordersClient;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public String pay(HttpServletRequest request, HttpServletResponse response,Map maps) throws IOException {
        Integer uid = Integer.valueOf(maps.get("uid").toString());
        Integer bid = Integer.valueOf(maps.get("bid").toString());
        Double price = Double.valueOf(maps.get("price").toString())/100;
        Integer did = Integer.valueOf(maps.get("did").toString());
        UUID uuid = UUID.randomUUID();
        String string1 = uuid.toString();
        Orders orders = new Orders();
        orders.setBid(bid);
        orders.setUid(uid);
        orders.setPrice(price);
        orders.setDid(did);
        orders.setOnumber(string1);
        orders.setDName("奶茶");
//        调用支付时，先添加订单
       ordersClient.add(orders);
//        添加成功后，删除购物车的信息
        redisTemplate.opsForHash().delete("SHOP_CART_"+orders.getUid().toString(),orders.getDid().toString());
        AlipayClient alipayClient =  new DefaultAlipayClient( url , APP_ID, APP_PRIVATE_KEY, "json", "utf-8", ALIPAY_PUBLIC_KEY, "RSA2");  //获得初始化的AlipayClient
        AlipayTradePagePayRequest alipayRequest =  new  AlipayTradePagePayRequest(); //创建API对应的request
        //同步-支付成功页面
        alipayRequest.setReturnUrl( "http://hzprw3.natappfree.cc/#/paySuccess" );
        //异步
        alipayRequest.setNotifyUrl( "http://fru8w9.natappfree.cc/pay/notifyUrl" ); //在公共参数中设置回跳和通知地址
        Map map = new HashMap<>();
        map.put("out_trade_no",orders.getOnumber());
        map.put("product_code","FAST_INSTANT_TRADE_PAY");
        map.put("total_amount",Double.valueOf(orders.getPrice().toString()));
        map.put("subject",orders.getDName());
        map.put("body","外卖");
        String string = JSONObject.toJSONString(map);
        alipayRequest.setBizContent(string);
        String form= "" ;
        try  {
            form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
        }  catch  (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }

    @Override
    public void notifyUrl(HttpServletRequest request,HttpServletResponse response) throws AlipayApiException {
        Map<String, String> stringStringMap = convertRequestParamsToMap(request);
        //Map<String, String> paramsMap = ... //将异步通知中收到的所有参数都存放到map中
        boolean signVerified = AlipaySignature.rsaCheckV1(stringStringMap, ALIPAY_PUBLIC_KEY, "utf-8", "RSA2"); //调用SDK验证签名
        if(signVerified){
            System.out.println(stringStringMap);
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            //得到订单号
            String out_trade_no = stringStringMap.get("out_trade_no");
            //用订单号去数据库查询订单
            BaseResp baseResp = ordersClient.findByOnumber(out_trade_no);
            Orders orders = (Orders)baseResp.getData();
            //得到需付款的钱数
            String total_amount = stringStringMap.get("total_amount");
            String[] split = total_amount.split("[.]");
            String[] split1 = orders.getPrice().toString().split("[.]");
            if(split[0].equals(split1[0])){
                //订单状态为成功
                orders.setState(stringStringMap.get("trade_state"));
                ordersClient.update(orders);
            }
        }else{
            // TODO 验签失败则记录异常日志，并在response中返回failure.
        }
    }


    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }
}
